//
// tetraTopology - class base for boundary contraction
// By Antonio Miranda, November 2010
//////////////////////////////////////////////////////////////////////////

#ifndef _TETRA_TOPOLOGY_3D_
#define _TETRA_TOPOLOGY_3D_

#include <vector>
#include <list>
#include <map>
#include <string>
#include "blockalloc.h"
#include "triface.h"
#include "tetraelem.h"
#include "node.h"
#include "box3d.h"

// defines
//////////////////////////////////////////////////////////////////////////

using namespace std;
class cTopology;

// Node information
//////////////////////////////////////////////////////////////////////////
class nodeInfo
{
public:
  int id;
protected:
private:
};

// class tetraTopology
//////////////////////////////////////////////////////////////////////////
class tetraTopology
{
public:
  tetraTopology(void);
  ~tetraTopology(void);

  // insert mesh
  void insertNode    (int id, double x, double y, double z);
  void insertElement (int id, int n, int *conn, int gauss, int mat);
  void process ( );


  // get mesh information
  int numNodes () {return (int) m_nodeMem.size(); }
  int numElems () {return (int) m_elems.size(); }
  int maxIdNode () {return (int) m_maxNodeId; }

  // get entity elements
  vector <triface   *> getFaces () {return m_faces;}
  vector <tetraelem *> getElems () {return m_elems;}
  vector <node      *> getNodes () {return m_nodes;}
  vector <triface   *> getBound () {return m_boundFaces;}

  // get a specific face
  triface *getFace (int i, int j, int k);


  //////////////////////////////////////////////////////////////////////////
  void printBoundFaces (char *file);

  // set/get Nodal information
  void insertNodalInf (string key, nodeInfo *info);
  void getNodalInfo (string key, vector <nodeInfo *> &info);


private:

  // memory manager
  blockalloc <triface>   m_faceMem;
  blockalloc <tetraelem> m_elemMem;
  blockalloc <node>      m_nodeMem;

  vector <triface   *> m_faces;
  vector <tetraelem *> m_elems;
  vector <node      *> m_nodes;
  vector <triface   *> m_boundFaces;

  // r-tree structures
  void *m_nodeTree;
  void *m_faceTree;

  // no
  multimap<string, nodeInfo*> m_nodalInf;

  // smallest edge
  double m_smallestFace;
  int    m_maxNodeId;

  // box
  Box3D box;

  void clear();
};

#endif
